package jp.tkym.labs.store;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

class DatastoreBindHelper{
	
	BindHelper4Rs create(ResultSet resultSet){
		return new BindHelper4Rs(resultSet);
	}
	
	BindHelper4Ps create(PreparedStatement preparedStatement){
		return new BindHelper4Ps(preparedStatement);
	}
	
	class BindHelper4Rs{
		private ResultSet rs;
		BindHelper4Rs(ResultSet resultSet){
			this.rs = resultSet;
		}
		
		Object getValue(String columnName, Class<?> type) throws SQLException{
			if(type.equals(String.class)) 	return rs.getString(columnName);
			if(type.equals(int.class)) 		return rs.getInt(columnName);
			if(type.equals(Integer.class)) 	return rs.getInt(columnName);
			if(type.equals(short.class)) 	return rs.getShort(columnName);
			if(type.equals(Short.class)) 	return rs.getShort(columnName);
			if(type.equals(Double.class)) 	return rs.getDouble(columnName);
			if(type.equals(double.class)) 	return rs.getDouble(columnName);
			if(type.equals(Float.class)) 	return rs.getFloat(columnName);
			if(type.equals(float.class)) 	return rs.getFloat(columnName);
			if(type.equals(Byte.class)) 	return rs.getByte(columnName);
			if(type.equals(byte.class)) 	return rs.getByte(columnName);
			if(type.equals(Date.class)) 	{
				long time = rs.getDate(columnName).getTime();
				return new Date(time);
			}
			throw new IllegalArgumentException(
					"unsupport class Type:"+type.getName());
		}
		
		Object get(String columnName, Class<?> classType, ResultSet rs) throws SQLException{
			try {
				if(classType.equals(String.class)) return rs.getString(columnName);
				if(classType.equals(int.class)) return rs.getInt(columnName);
				if(classType.equals(Integer.class)) return rs.getInt(columnName);
				if(classType.equals(long.class)) return rs.getLong(columnName);
				if(classType.equals(Long.class)) return rs.getLong(columnName);
				if(classType.equals(short.class)) return rs.getShort(columnName);
				if(classType.equals(Short.class)) return rs.getShort(columnName);
				if(classType.equals(double.class)) return rs.getDouble(columnName);
				if(classType.equals(Double.class)) return rs.getDouble(columnName);
				if(classType.equals(float.class)) return rs.getFloat(columnName);
				if(classType.equals(Float.class)) return rs.getFloat(columnName);
				if(classType.equals(byte.class)) return rs.getByte(columnName);
				if(classType.equals(Byte.class)) return rs.getByte(columnName);
				if(classType.equals(Date.class)){
					long time = rs.getDate(columnName).getTime();
					return new Date(time);
				}
			} catch (NullPointerException e) {
				String msg = 
					"NullPointer !! on get()" +
					"columnName="+columnName+
					", classType="+classType.getName();
				throw new IllegalArgumentException(msg, e);
			}
			return null;
		} 
	}
	
	class BindHelper4Ps{
		private PreparedStatement preparedStatement;
		private int index = 1;

		BindHelper4Ps(PreparedStatement preparedStatement){
			this.preparedStatement = preparedStatement;
		}
		
		private void setString(Object value) throws SQLException{
			this.preparedStatement.setString(index++, (String)value);
		}
		
		private void setInt(Object value) throws SQLException{
			this.preparedStatement.setInt(index++, (Integer)value);
		}
		
		private void setLong(Object value) throws SQLException{
			this.preparedStatement.setLong(index++, (Long)value);
		}
		
		private void setShort(Object value) throws SQLException{
			this.preparedStatement.setShort(index++, (Short)value);
		}
		
		private void setDouble(Object value) throws SQLException{
			this.preparedStatement.setDouble(index++, (Double)value);
		}
		
		private void setFloat(Object value) throws SQLException{
			this.preparedStatement.setFloat(index++, (Float)value);
		}
		
		private void setByte(Object value) throws SQLException{
			this.preparedStatement.setByte(index++, (Byte)value);
		}
		
		private void setDate(Object value) throws SQLException{
			long time = ((Date)value).getTime();
			this.preparedStatement.setDate(index++, new java.sql.Date(time));
		}
		
		void setValue(Object value) throws SQLException{
			if(value instanceof String) 	setString(value);
			if(value instanceof Integer)	setInt(value);
			if(value instanceof Long)		setLong(value);
			if(value instanceof Short)		setShort(value);
			if(value instanceof Double)		setDouble(value);
			if(value instanceof Float)		setFloat(value);
			if(value instanceof Byte)		setByte(value);
			if(value instanceof Date)		setDate(value);
			throw new IllegalArgumentException(
					"unsupport class Type:"+value.getClass().getName());
		}
		
		PreparedStatement preparedStatement(){
			return this.preparedStatement;
		}
	}
}